package com.example.demo.controller.multiThread;

import com.example.demo.entity.thread.*;
import com.example.demo.entity.ResultMsg;
import com.example.demo.entity.constants.AnotherThread;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author: zcb
 * @Description:
 * @Date: 2021/10/20
 */
@RestController
@RequestMapping("multiThread")
public class ThreadController {

    @GetMapping("startThread1")
    public ResultMsg startThread1() {
        MyThread myThread = new MyThread();
        myThread.start();

        return ResultMsg.ok();
    }

    @GetMapping("startThread2")
    public ResultMsg startThread2() {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        return ResultMsg.ok();
    }

    @GetMapping("startThread3")
    public ResultMsg startThread3() {
        Thread thread = new Thread(() -> {
            System.out.println("子线程再一次启动了。。。");
        });
        thread.start();
        return ResultMsg.ok();
    }

    //主线程等待子线程
    @GetMapping("waitingSubthread")
    public ResultMsg waitingSubthread() throws InterruptedException {
        System.out.println("主线程启动。。。");
        Thread thread = new Thread(() -> {
            System.out.println("子线程启动。。。");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子线程执行完毕。。。");
        });
        thread.start();

        //主线程等待子线程执行完毕
        thread.join();

        System.out.println("主线程执行完毕。。。");

        return ResultMsg.ok();
    }

    //中断子线程的执行
    @GetMapping("interruptSubthread")
    public void interruptSubthread() throws InterruptedException {
        System.out.println("主线程启动。。。");
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(1000);
        //给子线程发送中断信号
        thread.interrupt();
        //等待子线程执行完毕
        thread.join();
        System.out.println("主线程执行完毕。。。");
    }

    //中断子线程的执行
    @GetMapping("interruptByVolatile")
    public void interruptByVolatile() throws InterruptedException {
        System.out.println("主线程启动。。。");
        AnotherThread thread = new AnotherThread();
        thread.start();
        Thread.sleep(1);
        //修改子线程标志位
        thread.running = false;
        //等待子线程执行完毕
        thread.join();
        System.out.println("主线程执行完毕。。。");
    }

    //线程同步
    @GetMapping("sync")
    public void sync() throws InterruptedException {
        AddCountThread addCountThread = new AddCountThread();
        addCountThread.start();
        addCountThread.join();

        DecThread decThread = new DecThread();
        decThread.start();
        decThread.join();

        System.out.println(Count.count);
    }

    @GetMapping("pool")
    public String pool() throws ExecutionException, InterruptedException {
        ExecutorService executors =  Executors.newFixedThreadPool(4);
        List<Future<String>> futures = new ArrayList<>();
        List<String> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Callable<String> task = new CallableTask(i + "");
            futures.add(executors.submit(task));
        }
        for (Future<String> result : futures) {
            results.add(result.get());
        }
        return results.toString();
    }

    private static volatile int count = 0;

    @GetMapping("testVolatile")
    public ResultMsg testVolatile() {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
            }
        });
        Thread thread2 = new Thread(() -> {
           for (int i = 0; i < 1000; i++) {
               try {
                   Thread.sleep(1);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               count++;
           }
        });
        thread1.start();
        thread2.start();

        while (thread1.isAlive() || thread2.isAlive()) {}

        return ResultMsg.ok(count + "");
    }

}
